package geppetto.phraseTable.resource;

import java.util.ArrayList;
import java.util.LinkedList;

import geppetto.decoder.TranslationDecoder;
import geppetto.decoder.TranslationHypothesis;
import geppetto.decoder.TranslationHypothesisScore;
import geppetto.decoder.TranslationOption;
import geppetto.decoder.scores.GraphPhraseProductScore;
import geppetto.decoder.scores.NumberOfOptionsScore;
import geppetto.phraseHMM.phraseExtraction.extractedphrase.data.ReorderingGraphData;
import geppetto.phraseTable.PhraseTable;
import geppetto.phraseTable.PhraseTableListennerAdapter;
import geppetto.phraseTable.phrase.Phrase;
import geppetto.phraseTable.phrase.feature.ProbabilityFeature;

public class TranslationGraphResource extends PhraseTableListennerAdapter{

	protected final static String SUBPHRASES_HEADER = "reordering_graph";
	protected final static String PROB_HEADER = "prob";
	protected final static String RPROB_HEADER = "rprob";
	public final static String NUMBER_OF_OPTIONS = "noptions";
	public final static String PHRASE_WEIGHTING = "pweight";
	public final static String REVERSE_PHRASE_WEIGHTING = "rpweight";

	Phrase currentPhrase;
	LinkedList<TranslationHypothesis> finalHyps;
	TranslationDecoder decoder;
	int maxSourceSize=0;
	int maxTargetSize=0;
	
	@Override
	public void beforeCalculateFeature(Phrase p, PhraseTable table) {
		setCurrentPhrase(p,table);
	}
	
	@Override
	public void beforePruneCheckPhrase(Phrase p, PhraseTable table) {
		setCurrentPhrase(p,table);		
	}

	public LinkedList<TranslationHypothesis> getFinalHyps() {
		return finalHyps;
	}

	public void setFinalHyps(LinkedList<TranslationHypothesis> finalHyps) {
		this.finalHyps = finalHyps;
	}
	
	public TranslationHypothesisScore getScore(String name){
		return decoder.getOptionScore(name);
	}

	protected void setCurrentPhrase(Phrase p, PhraseTable table){
		currentPhrase = p;
		maxSourceSize=0;
		maxTargetSize=0;

		LinkedList<TranslationOption> options = getHypothesisFromReorderingGraph(p, table);
		decoder = new TranslationDecoder(options, maxSourceSize, maxTargetSize);
		decoder.addOptionScore(NUMBER_OF_OPTIONS, new NumberOfOptionsScore());
		decoder.addOptionScore(PHRASE_WEIGHTING, new GraphPhraseProductScore(){
			@Override
			public double getPhraseScore(Phrase p) {
				return ((ProbabilityFeature)p._features.getFeature(PROB_HEADER)).getProbability();
			}
		});
		decoder.addOptionScore(REVERSE_PHRASE_WEIGHTING, new GraphPhraseProductScore(){
			@Override
			public double getPhraseScore(Phrase p) {
				return ((ProbabilityFeature)p._features.getFeature(RPROB_HEADER)).getProbability();
			}
		});
		finalHyps = decoder.getTranslationHypothesis();
	}
	
	protected LinkedList<TranslationOption> getHypothesisFromReorderingGraph(Phrase p, PhraseTable table){
		ReorderingGraphData data = (ReorderingGraphData)p.getData(SUBPHRASES_HEADER);
		int[] sourceIds = data.get_sourceIds();
		int[] targetIds = data.get_targetIds();
		short[] sourceSPs = data.get_sourceStartPos();
		short[] sourceEPs = data.get_sourceEndPos();
		short[] targetSPs = data.get_targetStartPos();
		short[] targetEPs = data.get_targetEndPos();
		LinkedList<TranslationOption> options = new LinkedList<TranslationOption>();
		System.out.println("-----");
		for(int i = 0; i < sourceEPs.length; i++){
			int sourceId = sourceIds[i];
			int targetId = targetIds[i];
			int sourceSP = sourceSPs[i];
			int sourceEP = sourceEPs[i];
			int targetSP = targetSPs[i];
			int targetEP = targetEPs[i];
			int sourceSize = sourceEP - sourceSP + 1;
			int targetSize = targetEP - targetSP + 1;
			Phrase subphrase = table.getPhrase(sourceId, targetId, sourceSize, targetSize);
			TranslationOption option = new TranslationOption(subphrase, sourceSP, sourceEP, targetSP, targetEP);
			options.add(option);
			if(maxSourceSize < sourceEP + 1){
				maxSourceSize = sourceEP + 1;
			}
			if(maxTargetSize < targetEP + 1){
				maxTargetSize = targetEP + 1;
			}
			System.out.println(sourceId + ":" + targetId + ":" +sourceSP+":"+sourceEP+":"+targetSP+":"+targetEP);
		}
		System.out.println("-----");
		return options;
	}
}
